package com.ransj.iphone.view;

import com.ransj.iphone.IKey;
import com.ransj.iphone.IKeyListener;
import com.ransj.iphone.R;
import com.ransj.iphone.SpKey;
import com.ransj.iphone.utils.ILog;
import com.ransj.iphone.utils.IUtils;
import com.ransj.iphone.utils.Isp;
import com.ransj.iphone.view.ILinearLayout.MyOnTouchListener;

import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

/**
 * custom view
 * 
 * @author ranshengju
 * 
 */
public class FloatView extends AbsView implements MyOnTouchListener{
	private static final String TAG = FloatView.class.getSimpleName();
	private static final int DISTANCE_FILTER = 20;
	private static final int MINI_TIME_LENGTH = 1000;//1.5s
	private static int MINI_RECT_WIDTH;
	private static int MINI_RECT_HEIGHT;
	private boolean mIsMoveable;
	private int mLastX, mLastY, mParamsX, mParamsY;
	private int mKeyCode;
	private boolean mIsEnterMiniRect;
	private boolean mCanMinus;
	private boolean mIsMove;
	private Handler mHandler;
	private View mTouchView;
	private int mTitleBarHeight;
	private Runnable mMiniRunnable;

	private FloatView() {
		mIsMoveable = true;
		mHandler = new Handler();
	}

	public static FloatView createView(View view, View touchView, LayoutParams params) {
		FloatView temp = new FloatView();
		temp.init(view, touchView, params);
		return temp;
	}
	
	public void init(View view, View touchView, LayoutParams params){
		mMainView = view;
		mTouchView = touchView;
		mWMParams = params;
		mTitleBarHeight = IUtils.getStatusBarHeight(view.getContext());
		MINI_RECT_WIDTH = (int) view.getContext().getResources().getDimension(R.dimen.mini_rect_width);
		MINI_RECT_HEIGHT = (int) view.getContext().getResources().getDimension(R.dimen.mini_rect_height);
		if(mTouchView != null){
			((ILinearLayout)touchView).setMyOnTouchListener(this);
			touchView.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					if (mKeyListener != null) {
						mKeyListener.onKeyEvent(FloatView.this, mKeyCode);
					}
				}
			});
		}
	}

	public void setMoveable(boolean moveable) {
		mIsMoveable = moveable;
		if(mTouchView != null){
			((ILinearLayout)mTouchView).setMoveable(moveable);
		}
	}

	@Override
	public void setWindowManager(WindowManager manager) {
		super.setWindowManager(manager);
	}

	private void checkBestPosition(int x, int y) {
		int mScreenWidth = mWMManager.getDefaultDisplay().getWidth();
		int mScreenHeight = mWMManager.getDefaultDisplay().getHeight()
				- mTitleBarHeight;
		int dis_x = x > (mScreenWidth >> 1) ? (mScreenWidth - x) : x;
		int dis_y = y > (mScreenHeight >> 1) ? (mScreenHeight - y) : y;
		if (dis_y < dis_x) {
			mWMParams.x = x;
			mWMParams.y = y > (mScreenHeight >> 1) ? mScreenHeight : 0;
		} else {
			mWMParams.x = x > (mScreenWidth >> 1) ? mScreenWidth : 0;
			mWMParams.y = y;
		}
		try {
			mWMManager.updateViewLayout(mMainView, mWMParams);
		} catch (Exception e) {
		}
		Isp.getInstance(null).getPrefs().edit()
		.putInt(SpKey.MAIN_X, mWMParams.x/mScreenWidth)
		.putFloat(SpKey.MAIN_Y, (float)mWMParams.y/(float)mScreenHeight)
		.commit();
	}

	public void setOnKeyEventListener(IKeyListener listener, int keyCode) {
		mKeyListener = listener;
		mKeyCode = keyCode;
	}

	@Override
	public boolean onUp(MotionEvent e) {
		if(mIsEnterMiniRect){
			mIsEnterMiniRect = false;
			cancelScheduleToMinimus();
			mKeyListener.onKeyEvent(this, IKey.KEY_MINI_EXIT);
		}
		if (mIsMoveable && mIsMove) {
			checkBestPosition((int) e.getRawX(), (int) e.getRawY());
		}
		mIsEnterMiniRect = false;
		return true;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		return false;
	}

	@Override
	public boolean onDoubleTap(MotionEvent e) {
		return true;
	}

	@Override
	public boolean onDown(MotionEvent e) {
		mLastX = (int) e.getRawX();
		mLastY = (int) e.getRawY();
		mParamsX = mWMParams.x;
		mParamsY = mWMParams.y;
		mIsMove = false;
		return true;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		if (mIsMoveable) {
			int dx = (int) e2.getRawX() - mLastX;
			int dy = (int) e2.getRawY() - mLastY;
			if (Math.abs(dx) > DISTANCE_FILTER
					|| Math.abs(dy) > DISTANCE_FILTER) {
				mIsMove = true;
				mWMParams.x = mParamsX + dx;
				mWMParams.y = mParamsY + dy;
				try {
					// ������λ��
					mWMManager.updateViewLayout(mMainView, mWMParams);
				} catch (Exception e) {
					ILog.getInstance().e(TAG, e);
				}
				if (mCanMinus) {
					isEnterMiniRect(mWMParams.x, mWMParams.y);
				}
			}
		}
		return true;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		ILog.getInstance().w("TAG", "onLongPress...");
		if (mKeyListener != null) {
			mKeyListener.onKeyEvent(FloatView.this, IKey.KEY_MAIN_LONG_PRESS);
		}
	}
		
	
	public void setCanMinus(boolean minus){
		mCanMinus = minus;
	}

	/**
	 * check if enter mini rect
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	private boolean isEnterMiniRect(int x, int y) {
		int mScreenWidth = mWMManager.getDefaultDisplay().getWidth();
		int mScreenHeight = mWMManager.getDefaultDisplay().getHeight()
				- mTitleBarHeight;
		int height_start = (mScreenHeight - MINI_RECT_HEIGHT) >> 1;
		if(mTouchView != null){
			height_start = height_start - mTouchView.getHeight();
		}
		int height_end = (mScreenHeight + MINI_RECT_HEIGHT) >> 1;
		if (mScreenWidth - x - mMainView.getWidth() < MINI_RECT_WIDTH
				&& height_start < y && y < height_end) {
			if (!mIsEnterMiniRect) {
				scheduleToMinimus();
				if (mKeyListener != null) {
					mKeyListener.onKeyEvent(FloatView.this, IKey.KEY_MINI_ENTER);
				}
			}
			mIsEnterMiniRect = true;
			ILog.getInstance().d(TAG, "enter mini rect");
		} else if(mIsEnterMiniRect){
			cancelScheduleToMinimus();
			mIsEnterMiniRect = false;
			mKeyListener.onKeyEvent(FloatView.this, IKey.KEY_MINI_EXIT);
		}
		return mIsEnterMiniRect;
	}
	
	private void scheduleToMinimus(){
		if (mMiniRunnable == null) {
			mMiniRunnable = new Runnable() {

				@Override
				public void run() {
					if (mIsEnterMiniRect) {
						mIsMove = false;
						if (mKeyListener != null) {
							mKeyListener.onKeyEvent(FloatView.this,
									IKey.KEY_MAIN_MINUS);
						}
						ILog.getInstance().w(TAG, "hit mini rect");
					}
				}
			};
		}
		mHandler.postDelayed(mMiniRunnable, MINI_TIME_LENGTH);
	}
	
	private void cancelScheduleToMinimus(){
		if(mMiniRunnable != null){
			mHandler.removeCallbacks(mMiniRunnable);
			mMiniRunnable = null;
		}
	}

	@Override
	public void dispathWindowManager() {
		super.dispathWindowManager();
		mIsEnterMiniRect = false;
	}
	
	
}
